<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // this  -> 函数的内置参数,每个函数都有,一般指向函数调用时依存的对象
    // (1)  普通函数,调用时没有依存的对象  this -> window (严格模式下指向undefined)
    // (2)  函数调用时有依存的对象,调用时属于谁就指向谁  => obj.sum()  btn.onclick = function(){}
    // (3)  构造函数中this指向,构造函数在执行过程中创建的实例化对象   new XXX()
    // (4)  箭头函数没有自己的this指向,它的this依赖于上层作用域(父作用域)this指向,如果上层函数也是箭头函数,继续向外跳一层,以此类推,如果跳到全局 this->window   (注意: 箭头函数不能作为构造函数)

    // 改变this指向的三个方法  call  apply  bind (存在于Function.prototype)  => 所有的函数都可以使用
    // (1) 函数都是由构造函数Function创建, 所有的函数都可以访问 Function.prototype




    // call(thisArg,arg1,arg2,...argN) 
    // (1) 调用原函数
    // (2) 在本次函数执行过程中,强制将this指向call()的第一参数,如果参数是null和undefined默认将this指向window
    // (3) 如果原函数需要接收参数, 从第二参数开始依次向后传


    // apply(thisArg,[arg1,arg2,...argN]) 
    // (1) 调用原函数
    // (2) 在本次函数执行过程中,强制将this指向apply()的第一参数,如果参数是null和undefined默认将this指向window
    // (3) 如果原函数需要接收参数, 先将参数整合到数组中,再将数组作为第二参数传入


    // call  apply  => 调用原函数,在本次函数执行过程中,强制将this指向call/apply()的第一参数
    // 规律: 借鸡生蛋  


    // bind(thisArg)
    // (1) 根据原函数生成一个新函数
    // (2) 新函数调用时this一直指向bind()方法的第一参数 (bind参数中提前订好的)
    // (3) 如果新函数需要接收参数
    //     a. bind()方法生成新函数时,提前将参数定死
    //     b. bind()方法生成新函数时,没有定参数,可以在新函数调用时传入
    //     c. bind()方法生成新函数时,将部分参数定死, 新函数调用时传入一部分

    // bind  => 根据原函数生成一个新函数,不改变原函数
    // 规律: 授人以鱼不如授人以渔

    function fn(a, b) {
        console.log("函数fn被调用了", this);
        console.log("函数的参数", a, b);
    }

    // var newFn = fn.bind(document);
    // console.log(newFn);
    // console.log(newFn === fn);  // false

    // newFn();
    // newFn();
    // newFn();
    // newFn();
    // newFn();

    function fn(a, b) {
        console.log("函数fn被调用了", this);
        console.log("函数的参数", a, b);
    }

    // var newFn = fn.bind(document, 1, 2);  //  bind()方法生成新函数时,提前将参数定死
    // newFn();
    // newFn();
    // newFn();
    // newFn();

    // var newFn = fn.bind(document);
    // newFn(1, 2);
    // newFn(3, 4);
    // newFn(5, 6);


    var newFn = fn.bind(document, 1);
    newFn(2);
    newFn(4);
    newFn(6);









</script>

</html>